#!/usr/local/bin/perl
use XML::Writer;
use IO::File;
use WWW::Mechanize;
use HTML::TreeBuilder;
use Data::Dumper;
use lib './';
use wxml;
use utf8;
my $url = "http://gatherer.wizards.com/Pages/Default.aspx";

my $mech = WWW::Mechanize->new();

my @sets;
my @cards;
$mech->get( $url );

my $tree = new HTML::TreeBuilder;

$tree->parse($mech->content);

my $select = ($tree->find_by_attribute('id', 'ctl00_ctl00_MainContent_Content_SearchControls_setAddText'))[0];

foreach my $opt ($select->find_by_tag_name('option'))
{
	push @sets, $opt->attr('value') if $opt->attr('value');
}

undef $tree;

my $search_url = 'http://gatherer.wizards.com/Pages/Search/Default.aspx?output=%s&sort=p+&action=advanced&special=true&set=["%s"]';
my $total = scalar(@sets);
my $count = 0;




	my $output = new IO::File(">./output.xml");

	my $writer = new XML::Writer(OUTPUT => $output);
	$writer->startTag("mtgdb");





foreach my $set (@sets)
{
	my $mech = WWW::Mechanize->new();
	
	$count++;
	printf("%s of %s\n", $count, $total);
	
	my $names_to_id = {};
	my $checklist = sprintf($search_url, "checklist", $set);
	$mech->get($checklist);
	my $tree = new HTML::TreeBuilder;

	$tree->parse($mech->content);
	
	my $table = ($tree->find_by_attribute('class', 'checklist'))[0];

	foreach my $tr ($table->find_by_tag_name('tr'))
	{
		next if ($tr->attr('class') ne 'cardItem');
		my $name = ($tr->find_by_attribute('class', 'name'))[0]->as_text;
		my $id = ($tr->find_by_attribute('class', 'number'))[0]->as_text;
		my $url = ($tr->find_by_attribute('class', 'nameLink'))[0]->attr('href');
		$names_to_id->{$name}->{'id'} = $id;
		$names_to_id->{$name}->{'url'} = 'http://gatherer.wizards.com/Pages/Search/' .$url; 
	}
	
	undef $tree;
	
	my $spoiler = sprintf($search_url, "spoiler", $set);
	$mech->get($spoiler);
	$tree = new HTML::TreeBuilder;

	$tree->parse($mech->content);
	my @divs = $tree->find_by_tag_name('div');
	
	foreach my $div (@divs)
	{
		my $next_card = 0;
		
		if ($div->attr('class') eq 'textspoiler')
		{
			my @trs = $div->find_by_tag_name('tr');
			my $card =
			{
				'set' => $set,
				'short' => $short,
			};
			
			foreach my $tr (@trs)
			{
				
				if ($tr->as_text =~/^\s+$/io)
				{
					
					$card->{'id'} = $names_to_id->{$card->{'name'}}->{'id'};
					$card->{'card_url'} = $names_to_id->{$card->{'name'}}->{'url'};
					push @cards, $card;
					
					undef $card;
					
					$card = 
					{
						'set' => $set,
						'short' => $short,
					};
					
					
					next;
				}
	
				my $string = $tr->as_text();
				
				$string =~ s/^\s+//go;
				$string =~ s/\s+$//go; 
				my ($name, $value) = ($1, $2)  if ($string =~ /^(.+?):(.+?)$/);
				
				$value =~ s/^\s+//o;
				$value =~ s/\s+$//o;
				
				parse_name($name, $value, $card);
				parse_cost($name, $value, $card);
				parse_type($name, $value, $card);
				parse_pb($name, $value, $card);
				parse_text($name, $value, $card);
				parse_rare($name, $value, $card);
				
				
			} 				
		}
	}
	
	write_xml(\@cards);
	undef @cards;
	undef $tree; 
	undef $mech;
}

	$writer->endTag("mtgdb");
	$writer->end();



sub write_xml
{
	my $arr = shift;
		
	foreach my $item (@$arr)
	{
		$writer->startTag("card");
		
		foreach my $k (keys %$item)
		{
			utf8::encode($k);
			utf8::encode($item->{$k});
			
			$writer->startTag($k);
				$writer->characters($item->{$k});
			$writer->endTag($k);
		}
		
		
		$writer->endTag("card");
	}
}

sub parse_rare
{
	my ($name, $value, $card) = @_;
	
	unless($name =~ /set\/rarity/io)
	{
		return;
	}
	
	if ($card->{'type'} =~ /land/io)
	{
		$card->{'rare'} = 'Land';
		return;
	}
	my @sets = split(', ', $value);
	my @parts = split(' ', $sets[0]);
	
	if ($parts[-2] eq 'Mythic')
	{
		$card->{'rare'} = 'Mythic Rare'
	}
	else
	{
		$card->{'rare'} = $parts[-1];
	}

	

	
	
}

sub parse_text
{
	my ($name, $value, $card) = @_;
	
	unless($name =~ /rules\stext/io)
	{
		return;
	}
	
	$card->{'text'} = $value;	
	
}

sub parse_pb
{
	my ($name, $value, $card) = @_;
	
	unless($name =~ /pow\/tgh/io)
	{
		return;
	}
	my ($a, $b) = ($1, $2) if ($value =~ /^\((.+?)\/(.+?)\)$/o);
	
	$card->{'attack'} = $a;
	$card->{'block'} = $b;	
}

sub parse_type
{
	my ($name, $value, $card) = @_;
	
	unless($name =~ /type/io)
	{
		return;
	}

	$value=~ s/\x{2014}/-/ig;

	my ($t, $st) = ($1, $2) if ($value =~ /^(.+?)\s+-\s+(.+?)$/o);

	if ($t && $st)
	{
		$card->{'type'} = $t;
		$card->{'subtype'} = $st;
		
		$card->{'fulltype'} = $value;
	}
	else
	{
		$card->{'type'} = $card->{'fulltype'} = $value;
	}
}

sub parse_name
{
	my ($name, $value, $card) = @_;
	
	unless($name =~ /name/io)
	{
		return;
	}
	
	my ($r, $e) = ($1, $2) if ($value =~ /(.+?)\s\((.+?)\)/o);
	if (!$r && !$e)
	{
		$e = $value;
	}

	$card->{'name'} = $e;
	
}

sub parse_cost
{
	my ($name, $value, $card) = @_;
	
	unless($name =~ /cost/io)
	{
		return;
	}
	
	$card->{'mana'} = $value;
}





